Home |
| Latest | About | Random
# Week 2 Friday. Dear Class, Today I want discuss the **input buffer** of section 7. Homework 2 posted, due next Thursday. In [[1-teaching/ucla-2026-fall-pic-10a/Week-2-Wednesday|Wednesday's lecture notes]] there's a **DNA analysis example** in the postscript (scroll to bottom), using the various member functions of the `string` class to do string manipulations (such as `length`, `substr`, `find`, `rfind`, and `operator+`, ). You should try it for practice yourself. This may help with the homework somewhat. (I may make a video on it.) **Please read sections 6 and 7 for more examples and details! And if you are done with those, start section 8 (Control flow)!** -- B. . . . . . . . . ## The mystery of `cin` and `getline`, and `cin.ignore`. We've been using `std::cin` to take user input. By the way, `std::cin` is actually an **instance** of the `std::istream` class (in particular `cin` has *member functions*, as we will see). But `cin` behaves oddly when there's a space in the input. ```cpp #include #include using namespace std; int main(){ string color, sentence; double number; cout << "Give me a color: "; cin >> color; cout << "Give me a number: "; cin >> number; cout << "Your color is " << color << " and your number is " << number << endl; cout << "Give me a beautiful sentence:\n"; cin >> sentence; cout << "Your sentence is\n" << sentence; return 0; } ``` It only seems to capture the part just before the space ` `, and things really mess up if you have spaces anywhere! This also break when we try to enter a non-double for a double. We can use the *free function* `std::getline(cin, str)` to help with this, where `str` is a `string`. This will try to save things as a `string`. In isolation by itself `getline` seems to work: ```cpp #include #include using namespace std; int main(){ string sentence; cout << "Give me a beautiful sentence:\n"; getline(cin, sentence); cout << "Your sentence is\n" << sentence << endl; return 0; } ``` Great! `getline(cin, str)` seems to capture everything including the spaces! . . . . . Or does it? Try having both `cin >> word` and `getline(cin, sentence)` together like so ```cpp #include #include using namespace std; int main(){ string word, sentence; cout << "Give me a word:\n"; cin >> word; cout << "Give me a beautiful sentence:\n"; getline(cin, sentence); cout << "Your word is\n" << word << endl; cout << "Your sentence is\n" << sentence << endl; return 0; } ``` You will find that `cin` and `getline` interact weirdly. What's even more weird is we can "fix" this by having `std::cin.ignore()` just before we do `getline`. Try adding `cin.ignore()` before our `getline`. ```cpp #include #include using namespace std; int main(){ string word, sentence; cout << "Give me a word:\n"; cin >> word; cin.ignore(); cout << "Give me a beautiful sentence:\n"; getline(cin, sentence); cout << "Your word is\n" << word << endl; cout << "Your sentence is\n" << sentence << endl; return 0; } ``` What's happening?! . . . . . . . ## The input buffer. (Straight from the text) When a user of a program is allowed to type into the console and they type something and then press ENTER, the characters they type, including the newline character `\n`, go to an intermediate place called the "**input buffer**". - Programs start with an empty input buffer (and `std::cin` starts in a good state). - After users have entered input and pressed ENTER, a program can make use of the typed characters via the input buffer. - A program *may or may not* use all of the characters in the input buffer by the time it finishes execution. ### A first example. First let us get a rough idea about how the input buffer works. A program starts with an empty input buffer. Now suppose we have this program ```cpp #include using namespace std; int main(){ int x; cin >> x; return 0; } ``` As we run this program, the program waits for the user to input something at `cin`. Suppose the user types `123abc` and hits the `enter` key, the characters `123abc\n` are stored in the input buffer (note `\n` is the newline character associated to `enter`). Now, `cin` attempts to extract as much `int` as it can from the input buffer, in this case `123`. It stores `123` into `x`, leaving the input buffer to be `abc\n` now. ![[1-teaching/ucla-2026-fall-pic-10a/---files/input_buffer_demo.svg]] Now let's see this in more detail... ### How `cin >> variable` works. Suppose we already have `variable` declared and defined. ![[1-teaching/ucla-2026-fall-pic-10a/---files/cin.svg]] **Remark.** We can also chain `cin` with `>>` like in `cout`. So `cin >> a >> b;` can be thought of as `cin >> a ; cin >> b;`. Let's see some examples. **Example A.** When the following program runs, user types `123` then `ENTER`, followed by `4567` then `ENTER`. ```cpp #include using namespace std; int main(){ int x, y; cin >> x; // note these two lines same as cin >> y; // cin >> x >> y; return 0; } ``` ![[1-teaching/ucla-2026-fall-pic-10a/---files/cin_example_a.svg]] **Example A2.** When the following program runs, user types `123 4567` then `ENTER`. ```cpp #include using namespace std; int main(){ int x, y; cin >> x; // note these two lines same as cin >> y; // cin >> x >> y; return 0; } ``` ![[1-teaching/ucla-2026-fall-pic-10a/---files/cin_example_a2.svg]] **Example B.** When the following program runs, user types `123abc` then `ENTER`. ```cpp #include using namespace std; int main(){ int x, y; cin >> x; cin >> y; return 0; } ``` ![[1-teaching/ucla-2026-fall-pic-10a/---files/cin_example_b.svg]] **Example C.** When the following program runs, user types `Hi Mom!` then `ENTER`. ```cpp #include #include using namespace std; int main(){ string txt; cout << "Greet:\n"; cin >> txt; cout << txt; return 0; } ``` ![[1-teaching/ucla-2026-fall-pic-10a/---files/cin_example_c.svg]] **Try it!** Suppose we have added these two additional lines to above program. The program runs and the user types `Hi Mom!` and `ENTER`. Describe what would happen. ```cpp #include #include using namespace std; int main(){ string txt; cout << "Greet:\n"; cin >> txt; cout << txt; cin >> txt; // additional line cout << txt; // additional line return 0; } ``` ### How `getline(cin, str)` works. Suppose that a `string` called `str` has been declared and defined. ![[1-teaching/ucla-2026-fall-pic-10a/---files/getline.svg]] **Example D.** The following program runs. When possible, the user types `Lo` and `ENTER`. If possible, the user then types `My Liege!` and `ENTER`. ```cpp #include #include using namespace std; int main(){ string word, txt; cout << "Word? "; cin >> word; cout << "Sentence? "; getline(cin, txt); cout << "You say: " << word << " " << txt; return 0; } ``` ![[1-teaching/ucla-2026-fall-pic-10a/---files/getline_example_d.svg]] ### How `cin.ignore()` works. ![[1-teaching/ucla-2026-fall-pic-10a/---files/cin_ignore.svg]] **Example E.** The following program runs. When possible, the user types `Lo` and `ENTER`. If possible, the user then types `My Liege!` and `ENTER`. ```cpp #include #include using namespace std; int main(){ string word, txt; cout << "Word? "; cin >> word; cin.ignore(); cout << "Sentence? "; getline(cin, txt); cout << "You say: " << word << " " << txt; return 0; } ``` ![[1-teaching/ucla-2026-fall-pic-10a/---files/cin_ignore_example_e.svg]] **Try it!** What if instead the user first typed `Lo ` (**with a trailing space**), then `ENTER`? Can the user then type `My Liege!` , `ENTER`? What is the final output in the console? ### `cin.get()` and `cin.peek()`. Read the book and its review for more practice on these. **How `cin.get()` works.** Suppose `ch` is a `char` that is declared and defined, and suppose `cin` is not in a fail state. Then doing `ch = cin.get()` does: 1. If there are no characters in the input buffer, allow the user to enter input. 2. Extract the first character from the input buffer and assign it to `ch`. **How `cin.peek()` works.** Suppose `ch` is a `char` that is declared and defined, and suppose `cin` is not in a fail state. Then doing `ch = cin.peek()` does: 1. If there are no characters in the input buffer, allow the user to enter input. 2. Assign the first character in the input buffer to `ch` and leave it in the input buffer, that is, do not extract it from the input buffer. (There is also `cin.fail()`, `cin.clear()` in the text. Skim these but don't sweat too much.) **Some more practice. Also see text for more!** **(A) Predict what happens (the outputs, and what's in the input buffer)** Suppose the following program runs, and the first moment the user is allowed to type, the user types `abcd` followed by `ENTER`. ```cpp #include #include using namespace std; int main(){ string str; cin.ignore(); cin >> str; cout << str; return 0; } ``` **(B) Predict what happens (the outputs, and what's in the input buffer)** Suppose the following program runs, and the first moment the user is allowed to type, the user types `abcd` followed by `ENTER`. If we are allowed to type again, the user types `1234` followed by `ENTER`. ```cpp #include #include using namespace std; int main(){ string str; cin >> str; cin.ignore(); cout << str; return 0; } ``` **(C) Predict what happens (the outputs, and what's in the input buffer)** Suppose the following program runs, and the first moment the user is allowed to type, the user types `abcd` followed by `ENTER`. If we are allowed to type again, the user types `1234` followed by `ENTER`. ```cpp #include #include using namespace std; int main(){ string str; cin >> str; cin.ignore(); cin.ignore(); cout << str; return 0; } ``` ---